package com.ebt.m.customer.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.v4.util.LruCache;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import com.ebt.m.R;

import java.lang.ref.SoftReference;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class AvatarView extends View {

    public static final int[] COLORS = {0xffc4bfda,
            0xffb2dad4,
            0xffffe7d6,
            0xffe2edbe};

    private static final int COLORS_NUMBER = COLORS.length;

    private static final float DEFAULT_TEXT_SIZE_RATIO = 0.4f;
    private static final int DEFAULT_TYPE_BITMAP = 0;
    private static final int DEFAULT_TYPE_TEXT = 1;

    private String text;
    private int colorBg = COLORS[0];
    private float textSizeRatio = DEFAULT_TEXT_SIZE_RATIO;

    private Paint paintTextForeground;
    private Paint paintTextBackground;
    private Paint paintDraw;
    private Paint.FontMetrics fontMetrics;

    private static SoftReference<Bitmap> mDefaultCache; // 如果没有头像显示，默认显示的头像图片

    public AvatarView(Context context) {
        this(context, null);
    }

    public AvatarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AvatarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttr(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mMatrix = new Matrix();

        paintTextForeground = new Paint();
        paintTextForeground.setColor(0xffffffff);
        paintTextForeground.setAntiAlias(true);
        paintTextForeground.setTextAlign(Paint.Align.CENTER);

        paintTextBackground = new Paint();
        paintTextBackground.setColor(colorBg);
        paintTextBackground.setAntiAlias(true);
        paintTextBackground.setStyle(Paint.Style.FILL);

        paintDraw = new Paint();
        paintDraw.setAntiAlias(true);
        paintDraw.setStyle(Paint.Style.FILL);

//        mDefaultCache = new SoftReference<>(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_default_avatar));
        mDefaultCache = new SoftReference<>(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_default_proposal_head));
    }

    private void initAttr(Context context, AttributeSet attrs) {
        if (attrs == null) {
            return;
        }

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AvatarView);
        if (a == null) {
            return;
        }
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.AvatarView_aiv_textSizeRatio:
                    textSizeRatio = a.getFloat(attr, DEFAULT_TEXT_SIZE_RATIO);
                    break;
            }
        }
        a.recycle();
    }

    private int radius;
    private int paddingLeft;
    private int paddingTop;
    private int contentWidth;
    private int contentHeight;
    private int centerX;
    private int centerY;

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        paddingLeft = getPaddingLeft();
        paddingTop = getPaddingTop();
        contentWidth = w - paddingLeft - getPaddingRight();
        contentHeight = h - paddingTop - getPaddingBottom();

        radius = contentWidth < contentHeight ? contentWidth / 2 : contentHeight / 2;
        centerX = paddingLeft + radius;
        centerY = paddingTop + radius;
        refreshTextSizeConfig();
    }

    private void refreshTextSizeConfig() {
        paintTextForeground.setTextSize(textSizeRatio * 2 * radius);
        fontMetrics = paintTextForeground.getFontMetrics();
    }

    public void setTextAndColor(String text, int colorBg) {
        if (this.type != DEFAULT_TYPE_TEXT || text != this.text || colorBg != this.colorBg) {
            this.text = text;
            this.colorBg = colorBg;
            this.type = DEFAULT_TYPE_TEXT;
            invalidate();
        }
    }

    public void setTextAndColorSeed(String text, String colorSeed) {
        setTextAndColor(text, getColorBySeed(colorSeed));
    }

    private Bitmap bitmap;

    public void setBitmap(Bitmap bitmap) {
        if (bitmap == null) {
            return;
        }
        if (this.type != DEFAULT_TYPE_BITMAP || bitmap != this.bitmap) {
            this.bitmap = bitmap;
            this.type = DEFAULT_TYPE_BITMAP;
            invalidate();
        }
    }

    public void setDrawable(Drawable drawable) {
        Bitmap bitmap = getBitmapFromDrawable(drawable);
        setBitmap(bitmap);
    }

    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
    private static final int COLORDRAWABLE_DIMENSION = 1;

    private Bitmap getBitmapFromDrawable(Drawable drawable) {
        if (drawable == null) {
            return null;
        }

        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }

        try {
            Bitmap bitmap;

            if (drawable instanceof ColorDrawable) {
                bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
            } else {
                bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
            }

            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private int type = DEFAULT_TYPE_BITMAP;

    boolean clearFlag = false;

    public void clear() {
        clearFlag = !clearFlag;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (bitmap != null && type == DEFAULT_TYPE_BITMAP) {
            drawBitmap(canvas);
        } else if (text != null && type == DEFAULT_TYPE_TEXT) {
            drawText(canvas);
        }
    }

    private BitmapShader mBitmapShader;
    private Matrix mMatrix;
    private int bitmapWidth;
    private int bitmapHeight;

    private void drawBitmap(Canvas canvas) {

        bitmapWidth = bitmap.getWidth();
        bitmapHeight = bitmap.getHeight();

        int bSize = Math.min(bitmapWidth, bitmapHeight);
        float scale = radius * 2.0f / bSize;
        mMatrix.reset();
        mMatrix.setScale(scale, scale);
        if (bitmapWidth > bitmapHeight) {
            mMatrix.postTranslate(-(bitmapWidth * scale / 2 - radius - getPaddingLeft()), getPaddingTop());
        } else {
            mMatrix.postTranslate(getPaddingLeft(), -(bitmapHeight * scale / 2 - radius - getPaddingTop()));
        }

        mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
        mBitmapShader.setLocalMatrix(mMatrix);

        paintDraw.setShader(mBitmapShader);
        canvas.drawCircle(centerX, centerY, radius, paintDraw);

    }

    private void drawText(Canvas canvas) {
        paintTextBackground.setColor(colorBg);
        canvas.drawCircle(centerX, centerY, radius, paintTextBackground);
        canvas.drawText(text, 0, text.length(), centerX, centerY + Math.abs(fontMetrics.top + fontMetrics.bottom) / 2, paintTextForeground);
    }

    public int getColorBySeed(String seed) {
        if (TextUtils.isEmpty(seed)) {
            return COLORS[0];
        }
        return COLORS[Math.abs(seed.hashCode()) % COLORS_NUMBER];
    }


    //static function to add image to avatarview, using rxandroid
    public static void updateAvatarView(AvatarView avatarView,
                                        LruCache<String, Bitmap> cache,
                                        String cacheKey,
                                        String localImagePath,
                                        String textSeed) {

        Object tag = avatarView.getTag();
        Bitmap retBitmap = null;
        if (cache != null) {
            retBitmap = cache.get(cacheKey);
        }
        if (retBitmap != null) {
            if ((tag == null && avatarView.getTag() == null) || (tag != null && tag.equals(avatarView.getTag()))) {
                avatarView.setBitmap(retBitmap);
            }
        } else {

            Observable
                    .create(
                            new ObservableOnSubscribe<Bitmap>() {
                                @Override
                                public void subscribe(ObservableEmitter<Bitmap> emitter) throws Exception {
                                    Bitmap bitmap = null;
                                    if (!TextUtils.isEmpty(localImagePath)) {
                                        bitmap = BitmapFactory.decodeFile(localImagePath);
                                        if (bitmap != null && cache != null) {
                                            cache.put(cacheKey, bitmap);
                                        }
                                    }
                                    emitter.onNext(bitmap);
                                    emitter.onComplete();
                                }
                            })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeOn(Schedulers.io())
                    .subscribe(new Observer<Bitmap>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onComplete() {
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onNext(Bitmap b) {
                            if ((tag == null && avatarView.getTag() == null) || (tag != null && tag.equals(avatarView.getTag()))) {
                                if (b == null) {
                                    if (textSeed == null || TextUtils.isEmpty(textSeed.trim())) {
                                        avatarView.setTextAndColorSeed(" ", " ");
                                    } else {
                                        avatarView.setTextAndColorSeed(textSeed.trim().substring(0, 1), textSeed);
                                    }
                                } else {
                                    avatarView.setBitmap(b);
                                }
                            }
                        }
                    });
        }

    }

    /**
     * 计划书列表的更新头像
     *
     * @param avatarView
     * @param cache
     * @param cacheKey
     * @param localImagePath
     * @param textSeed
     */
    public static void updateAvatarViewAtSpans(AvatarView avatarView,
                                               LruCache<String, Bitmap> cache,
                                               String cacheKey,
                                               String localImagePath,
                                               String textSeed) {

        Object tag = avatarView.getTag();
        Bitmap retBitmap = null;
        if (cache != null) {
            retBitmap = cache.get(cacheKey);
        }
        if (retBitmap != null) {
            if ((tag == null && avatarView.getTag() == null) || (tag != null && tag.equals(avatarView.getTag()))) {
                avatarView.setBitmap(retBitmap);
            }
        } else {

            Observable
                    .create(
                            new ObservableOnSubscribe<Bitmap>() {
                                @Override
                                public void subscribe(ObservableEmitter<Bitmap> emitter) throws Exception {
                                    Bitmap bitmap = null;
                                    if (!TextUtils.isEmpty(localImagePath)) {
                                        bitmap = BitmapFactory.decodeFile(localImagePath);
                                        if (bitmap != null && cache != null) {
                                            cache.put(cacheKey, bitmap);
                                        }
                                    }
                                    emitter.onNext(bitmap);
                                    emitter.onComplete();
                                }
                            })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeOn(Schedulers.io())
                    .subscribe(new Observer<Bitmap>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onComplete() {
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onNext(Bitmap b) {
                            if ((tag == null && avatarView.getTag() == null) || (tag != null && tag.equals(avatarView.getTag()))) {
                                if (b == null) {
                                    if (textSeed == null || TextUtils.isEmpty(textSeed.trim())) {
                                        avatarView.setTextAndColor("", Color.parseColor("#ffb2dad4"));
                                    } else {
                                        String mHeadString = textSeed.trim().substring(0, 1);
                                        if (null == mHeadString || "".equals(mHeadString) || "?".equals(mHeadString)) {
                                            avatarView.setBitmap(mDefaultCache.get());
                                        } else {
                                            avatarView.setTextAndColor(mHeadString, Color.parseColor("#ffb2dad4"));
                                        }
                                    }
                                } else {
                                    avatarView.setBitmap(b);
                                }
                            }
                        }
                    });
        }

    }
}